package net.blank.effectClass
{
	import flash.display.DisplayObject;
	import flash.events.EventDispatcher;
	
	/**特效开始执行*/
	[Event(name="effect_start", type="EffectEvent")]
	
	/**特效执行结束*/
	[Event(name="effect_end", type="EffectEvent")]
	
	public class Move extends EventDispatcher
	{
		/** x 坐标特效对象*/
		private var _xEff:EffectForTimer;
		/** y 坐标特效对象*/
		private var _yEff:EffectForTimer;
		
		/**特效目标*/
		private var _target:DisplayObject;
		
		/** x 坐标开始值*/
		public var xFrom:int=int.MIN_VALUE;
		/** x 坐标终止值*/
		public var xTo:int=int.MIN_VALUE;
		
		/** y 坐标开始值*/
		public var yFrom:int=int.MIN_VALUE;
		/** y 坐标终止值*/
		public var yTo:int=int.MIN_VALUE;
		
		/**效果的持续时间*/
		public var duration:uint;
		
		/**延迟执行的时间*/
		public var delay:uint;
		
		/**重复执行的次数*/
		public var repeatCount:uint;
		/**重复执行时是否翻转*/
		public var isReversedForRepeat:Boolean;
		
		/**
		 * X轴坐标发生改变时的回调函数
		 * 此回调函数会将 Move 对象自身作为参数传回
		 */
		public var changeXCallback:Function;
		
		/**
		 * Y轴坐标发生改变时的回调函数
		 * 此回调函数会将 Move 对象自身作为参数传回
		 */
		public var changeYCallback:Function;
		
		/**附加信息*/
		public var additionalData:*;
		
		/**更改X坐标*/
		private function execX(curValue:int,target:*):void{
			target.x=curValue;
			
			if(changeXCallback != null){
				changeXCallback.apply(null,[this]);
			}
		}
		/**更改Y坐标*/
		private function execY(curValue:int,target:*):void{
			target.y=curValue;
			
			if(changeYCallback != null){
				changeYCallback.apply(null,[this]);
			}
		}
		
		/**重放*/
		private function replay():void{
			if(isReversedForRepeat){
				_xEff.Reversed();
				_yEff.Reversed();
			}
			_xEff.start();
			_yEff.start();
		}
		
		/**特效执行结束*/
		private function effectEnd(evt:EffectEvent):void{
			if(!_xEff.running && !_yEff.running){
				if(repeatCount > 0){
					replay();
					repeatCount--;
				}else{
					end();
				}
			}
		}
		
		/**添加侦听器*/
		private function regListener():void{
			_xEff.addEventListener(EffectEvent.EFFECT_END,effectEnd);
			_yEff.addEventListener(EffectEvent.EFFECT_END,effectEnd);
		}
		
		/**移除侦听器*/
		private function rmListener():void{
			_xEff.removeEventListener(EffectEvent.EFFECT_END,effectEnd);
			_yEff.removeEventListener(EffectEvent.EFFECT_END,effectEnd);
		}
		
		/**开始播放*/
		public function play(target:DisplayObject=null):void{
			if(target){
				_target=target;
				
				_xEff.target=_target;
				_yEff.target=_target;
			}
			
			var runTotalFrame:uint=duration / EffectForTimer.TIMER_25MS.delay;
			var startDelayFrame:uint=delay  / EffectForTimer.TIMER_25MS.delay;
			if(runTotalFrame > 0){
				regListener();
				
				dispatchEvent(new EffectEvent(EffectEvent.EFFECT_START));
				
				if(_xEff.target){
					if(xFrom != int.MIN_VALUE){
						_xEff.initValue=xFrom;
					}else{
						_xEff.initValue=_xEff.target.x;
					}
					
					if(xTo != int.MIN_VALUE){
						_xEff.endValue=xTo;
					}else{
						_xEff.endValue=_xEff.target.x;
					}
					_xEff.runTotalFrame=runTotalFrame;
					_xEff.startDelayFrame=startDelayFrame;
					
					_xEff.start(target);
				}
				
				if(_yEff.target){
					if(yFrom != int.MIN_VALUE){
						_yEff.initValue=yFrom;
					}else{
						_yEff.initValue=_yEff.target.y;
					}
					if(yTo != int.MIN_VALUE){
						_yEff.endValue=yTo;
					}else{
						_yEff.endValue=_yEff.target.y;
					}
					_yEff.runTotalFrame=runTotalFrame;
					_yEff.startDelayFrame=startDelayFrame;
					
					_yEff.start(target);
				}
			}
		}
		
		/**
		 * 
		 * @param xFrom
		 * @param yFrom
		 * @param target
		 * 
		 */
		public function from(xFrom:int,yFrom:int,target:DisplayObject=null):void{
			this.xFrom=xFrom;
			this.yFrom=yFrom;
			play(target);
		}
		
		/**
		 * 
		 * @param xTo
		 * @param yTo
		 * @param target
		 * 
		 */
		public function to(xTo:int,yTo:int,target:DisplayObject=null):void{
			this.xTo=xTo;
			this.yTo=yTo;
			play(target);
		}
		
		/**
		 * 
		 * @param xFrom
		 * @param yFrom
		 * @param xTo
		 * @param yTo
		 * @param target
		 * 
		 */
		public function fromTo(xFrom:int,yFrom:int,xTo:int,yTo:int,target:DisplayObject=null):void{
			this.xFrom=xFrom;
			this.yFrom=yFrom;
			this.xTo=xTo;
			this.yTo=yTo;
			
			play(target);
		}
		
		/**结束播放*/
		public function end():void{
			rmListener();
			
			_xEff.stop();
			_yEff.stop();
			
			repeatCount=0;
			
			dispatchEvent(new EffectEvent(EffectEvent.EFFECT_END));
		}
		
		/**重置*/
		public function reset():void{
			xFrom=int.MIN_VALUE;
			xTo=int.MIN_VALUE;
			yFrom=int.MIN_VALUE;
			yTo=int.MIN_VALUE;
			
			delay=0;
			repeatCount=0;
			isReversedForRepeat=false;
			
			changeXCallback=null;
			changeYCallback=null;
			
			additionalData=null;
		}
		
		public function Move(target:DisplayObject=null)
		{
			_target=target;
			
			_xEff=new EffectForTimer(_target);
			_xEff.execFunction=execX;
			
			
			_yEff=new EffectForTimer(_target);
			_yEff.execFunction=execY;
			
		}
		
		/**特效执行的目标*/
		public function set target(value:DisplayObject):void{
			if(value != _target){
				_target=value;
				
				_xEff.target=value;
				_yEff.target=value;
			}
		}
		public function get target():DisplayObject{
			return _target;
		}
		
		/**执行X坐标变化的特效对象*/
		public function get xEffect():EffectForTimer{
			return _xEff;
		}
		
		/**执行Y坐标变化的特效对象*/
		public function get yEffect():EffectForTimer{
			return _yEff;
		}
	}
}